<?php

declare(strict_types=1);

namespace app\model\admin;

use app\eslib\EsJwt;
use app\eslib\EsUtils;

/**
 * @mixin \think\Model
 */
class LoginState
{
    public $id = 0;
    public $appName = '';
    static $instance = null;

    /**
     * 构造方法
     */
    public function __construct($id = 0, $appName = 'admin')
    {
        $this->id = $id;
        $this->appName = $appName;
    }

    /**
     * 返回 ID 值
     */
    public static function getId()
    {
        return self::$instance ? self::$instance->id : 0;
    }
    public static function getJwtInfo($id, $appName = 'admin')
    {
        return EsJwt::encodeJWT(['id' => $id, 'app' => $appName]);
    }
    public static function getJwt($id, $withExp = true, $appName = 'admin')
    {
        $data = self::getJwtInfo($id, $appName);
        return $withExp ? ($data[1]['exp'] . '.' . $data[0]) : $data[0];
    }
    public static function checkJwt($appName = 'admin', $token = '')
    {
        self::$instance = new static();
        if (!$token) {
            // nginx 可以直接获取 headers 中的 Authorization 变量，apache 需要额外设置
            $request = request();
            $token = $request->header('Authorization', $request->param('token'));
        }
        if (!$token) {
            return EsUtils::stdMessage(false, 'Token 值无效');
        }
        $tokenInfo = EsJwt::decodeJWT($token);
        if (!$tokenInfo['success']) {
            return $tokenInfo;
        }

        $data = isset($tokenInfo['data']) ? (array) $tokenInfo['data'] : [];
        if (!isset($data['id']) || !isset($data['app'])) {
            return EsUtils::stdMessage(false, 'Token 值非法');
        }
        if ($data['app'] != $appName) {
            return EsUtils::stdMessage(false, 'AppName 错误' . $appName . '=' . $data['app']);
        }
        self::$instance->id = intval($data['id']);
        self::$instance->appName = $data['app'];
        return EsUtils::stdMessage(true, '', $data);
    }

    /**
     * [弃用] 因为要多写几行判断逻辑，不如使用中间件来得简洁。
     */
    public static function checkJWTForAction($appName, $onlyMethods = [], $exceptMethods = [])
    {
        $msgInfo = self::checkJwt();
        // 获取控制器的方法名称
        $action = \think\facade\Request::action();
        list($class, $method) = explode('@', $action);
        if ($onlyMethods && (!in_array($method, $onlyMethods))) {
            return EsUtils::stdMessage(true, '该方法无需权限检测');
        }
        if ($exceptMethods && (in_array($method, $exceptMethods))) {
            return EsUtils::stdMessage(true, '该方法无需权限检测');
        }
        if ($msgInfo['success']) {
            if ($appName != $msgInfo['data']['app']) {
                return EsUtils::stdMessage(false, 'AppName 错误');
            }
        }
        return $msgInfo;
    }
}
